#pragma once

#include <atlframe.h>
#include <atlcrack.h>
#include <atlmisc.h>
#include <atlscrl.h>
#include <atlctrls.h>
#include <atlwince.h>
#include "Theme.h"

// wParam is HDC to paint on
#define WM_HDCPAINT     (WM_USER + 1000)

class ATL_NO_VTABLE CBaseWindow : public ATL::CWindowImpl<CBaseWindow, CWindow, ATL::CControlWinTraits>
{
public:
  static ATL::CWndClassInfo& GetWndClassInfo()
  {
	  static ATL::CWndClassInfo wc =
	  {
		  { CS_HREDRAW | CS_VREDRAW, StartWindowProc,
      0, 0, NULL, NULL, NULL, (HBRUSH)(::GetStockObject(BLACK_BRUSH)), NULL, NULL },
		  NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
	  };
	  return wc;
  }

public:
// Message map and handlers
	BEGIN_MSG_MAP(CBaseWindow)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
    MESSAGE_HANDLER(WM_HDCPAINT, OnHdcPaint)
	END_MSG_MAP()

	LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		return bHandled = TRUE;   // no background needed
	}

  LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
  {
	  CPaintDC dc(this->m_hWnd);
    CRect rcPaint = dc.m_ps.rcPaint;
    if (rcPaint.IsRectNull())
      GetClientRect(&rcPaint);
    this->DoPaint(dc.m_hDC, rcPaint);
    return bHandled = TRUE;
  }

  LRESULT OnHdcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    CDCHandle dc((HDC)wParam);
    CRect rc;
    GetClientRect(&rc);
	  this->DoPaint(dc, rc);

    CRect rcChild;
    for(HWND hWndChild = ::GetWindow(m_hWnd, GW_CHILD); hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT))
    {
      ::GetWindowRect(hWndChild, &rcChild);
      ScreenToClient(&rcChild);
      dc.SetViewportOrg(rcChild.left, rcChild.top);
      ::SendMessage(hWndChild, uMsg, wParam, lParam);
    }
    dc.SetViewportOrg(0, 0);

    return bHandled = TRUE;
  }

protected:
// Overrideables
  virtual void DoPaint(CDCHandle dc, const CRect& rClip)
  {
    dc.FillRect(rClip, CTheme::brWindowBg);
    //RECT rClient;
    //GetClientRect(&rClient);
    //dc.Draw3dRect(&rClient, CTheme::clrWindowEdge, CTheme::clrWindowEdge);
  }

};